import express from 'express';
import cors from 'cors';
import helmet from 'helmet';
import morgan from 'morgan';
import cookieParser from 'cookie-parser';
import mongoSanitize from 'express-mongo-sanitize';
import xss from 'xss-clean';
import hpp from 'hpp';
import rateLimit from 'express-rate-limit';
import compression from 'compression';
import { StatusCodes } from 'http-status-codes';
import path from 'path';
import { fileURLToPath } from 'url';
import logger from './config/logger.js';
import { errorHandler, notFound } from './middlewares/error.js';
import routes from './routes/index.js';
import { sequelize, testConnection, syncModels } from './config/database.js';

const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

// 创建Express应用
const app = express();

// 1) 全局中间件

// 设置安全HTTP头，调整CSP配置
app.use(helmet({
  contentSecurityPolicy: {
    directives: {
      defaultSrc: ["'self'"],
      styleSrc: ["'self'", "'unsafe-inline'", "https:"],
      scriptSrc: ["'self'", "'unsafe-inline'", "'unsafe-eval'"],
      imgSrc: ["'self'", "data:", "https:"],
      connectSrc: ["'self'", "ws:", "wss:"],
      fontSrc: ["'self'", "https:", "data:"],
      objectSrc: ["'none'"],
      mediaSrc: ["'self'"],
      frameSrc: ["'self'"],
    },
  },
  crossOriginEmbedderPolicy: false
}));

// 开发环境日志
if (process.env.NODE_ENV === 'development') {
  app.use(morgan('dev'));
}

// 限制每个IP的请求速率
const limiter = rateLimit({
  max: process.env.NODE_ENV === 'production' ? 100 : 1000, // 生产环境限制100次/小时，开发环境1000次/小时
  windowMs: 60 * 60 * 1000, // 1小时
  message: '请求过于频繁，请稍后再试',
  standardHeaders: true,
  legacyHeaders: false,
});

// 应用API限流
app.use('/api', limiter);

// 解析JSON请求体
app.use(express.json({ limit: '10kb' }));

// 解析URL编码的请求体
app.use(express.urlencoded({ extended: true, limit: '10kb' }));

// 数据清理，防止NoSQL注入
app.use(mongoSanitize());

// 数据清理，防止XSS攻击
app.use(xss());

// 防止参数污染
app.use(hpp({
  whitelist: [
    'page',
    'limit',
    'sort',
    'fields',
    'populate'
  ]
}));

// 解析cookie
app.use(cookieParser());

// 启用CORS
const corsOptions = {
  origin: process.env.NODE_ENV === 'production' 
    ? process.env.CLIENT_URL 
    : 'http://localhost:5173',
  credentials: true,
  optionsSuccessStatus: 200
};
app.use(cors(corsOptions));

// 启用响应压缩
app.use(compression());

// 测试数据库连接并同步模型
const initializeDatabase = async () => {
  try {
    await sequelize.authenticate();
    logger.info('数据库连接成功');
    
    // 同步模型到数据库（开发环境下不修改表结构）
    if (process.env.NODE_ENV === 'development') {
      const isConnected = await testConnection();
      if (!isConnected) {
        throw new Error('数据库连接失败');
      }
      
      // 仅同步新表，不修改现有表结构
      await syncModels({ force: false, alter: false });
      
      logger.info('数据库初始化和模型同步完成');
    }
  } catch (error) {
    logger.error('数据库初始化失败:', error);
    // 不要退出进程，允许服务器继续运行
    logger.info('尽管数据库同步有错误，服务器将继续运行');
  }
};

testConnection();

// 初始化数据库
initializeDatabase();

// 2) 健康检查端点
app.get('/health', (req, res) => {
  res.status(StatusCodes.OK).json({
    status: 'success',
    message: '服务运行正常',
    timestamp: new Date().toISOString(),
    environment: process.env.NODE_ENV || 'development',
    nodeVersion: process.version,
  });
});

// 3) API 路由
app.use('/api', routes);

// 4) 静态文件服务（生产环境）
if (process.env.NODE_ENV === 'production') {
  // 设置静态文件夹
  app.use(express.static(path.join(__dirname, '../public')));
  
  // 处理前端路由，返回index.html
  app.get('*', (req, res) => {
    res.sendFile(path.resolve(__dirname, '../public', 'index.html'));
  });
} else {
  // 开发环境的catch-all路由
  app.all('*', (req, res, next) => {
    next(new Error(`找不到 ${req.originalUrl} 对应的路由`));
  });
}

// 5) 错误处理中间件
app.use(notFound);
app.use(errorHandler);

// 未捕获的异常处理
process.on('unhandledRejection', (err) => {
  logger.error('未处理的Promise拒绝:', err);
  // 记录错误并继续运行
  logger.error(err);
});

process.on('uncaughtException', (err) => {
  logger.error('未捕获的异常:', err);
  // 记录错误并退出进程
  logger.error(err);
  process.exit(1);
});

export default app;
